#!/usr/bin/env python
# -*- coding: utf-8 -*- 

#Kiwi Bot
#Copyright (C) 2009 Mathieu "MathX" Xhonneux
#Modified by @nge1nCorsic4 in 2011


#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License along
#with this program; if not, write to the Free Software Foundation, Inc.,
#51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import kiwi, kiwi.plugin, kiwi.events, kiwi.lang,  kiwi.config
import time, re
 # pickle, urllib, threading,
#from os.path import isfile, getmtime

#Banlist structure : [ [ Method, Time, Content, Pseudo, Reason ] * X ]

class ban(kiwi.plugin.Plugin):
	def onStart(self):
		self.lang = kiwi.lang.Lang(self,'ban')
		self.bdBan = kiwi.bd.bd_ban()
		ServNumber = kiwi.config.configuration().kiwi.kiwidir
		self.config = kiwi.config.configuration('@kiwi/conf/'+ServNumber+'/ban.cfg')
		self.registerEvent(kiwi.events.EVT_CLIENT_INFO, self.checkClient)
		self.registerEvent(kiwi.events.EVT_CLIENT_DISCONNECT, self.decoClient)
		self.decoList = None
		self.ClientsList = []
		self.register = self.main.getPlugin('admin').mod.registerCommand
		self.register('ban', int(self.config.rights.ban), self._ban, "000401")
		self.register('be', int(self.config.rights.be), self._be, "000401")
		self.register('bye', int(self.config.rights.bye), self._bye, "000405")
		self.register('unban', int(self.config.rights.unban), self._unban, "000414")
	def onStop(self):
		self.main.getPlugin('admin').mod.deleteCommand('ban')
		self.main.getPlugin('admin').mod.deleteCommand('unban')
		self.main.getPlugin('admin').mod.deleteCommand('bye')
		self.majbanlist(False)
	def banClient(self, event, banTime, arguments):
		clients = self.clients.getClientByInput(event.arguments[0])
		if len(clients) == 0:
			self.output.tell(event.id, self.lang.lang(event,"00103"))
		elif len(clients) == 1:
			guid, ip, name = clients[0].guid,clients[0].ip,clients[0].name
			Admin = self.clients.getClientById(event.id)[0].name
			self.output.send("kick %s"%(clients[0].id))
			self.bdBan.insertBan(guid,ip,name,banTime,Admin,arguments)
			self.output.tell(event.id,self.lang.lang(event,"00403"))
			self.output.send(self.lang.lang('',"00402")%(name, arguments))
			self.main.log.ban(self.lang.lang('',"00404")%(Admin, name, arguments))
		else:
			self.output.tell(event.id,self.lang.lang(event,"00104"))
	def checkClient(self, event):
		guid, ip, name, port = None, None, None, None
		hack = False
		if 'name' in event.vars:
			name = event.vars['name']
		if 'cl_guid' in event.vars:
			guid = event.vars['cl_guid']
			clients = self.bdBan.searchByGuid(guid)
			if clients :
				for client in clients :
					# print client['timeban'] , kiwi.getTime()
					if client['timeban'] == 0 or client['timeban'] > kiwi.getTime():
						self.output.send("kick %s"%(event.id))
						return
			hack = self.checkClientHack(guid)
		# else:
			# print 'not cl_guid : ', event.id
		if 'ip' in event.vars:
			cl_ip = event.vars['ip'].split(':')
			ip = cl_ip[0]
			port = cl_ip[1]
			clients = self.bdBan.searchByIp(ip)
			if clients :
				for client in clients :
					# print client['timeban'] , kiwi.getTime()
					if client['timeban'] == 0 or client['timeban'] > kiwi.getTime():
						self.output.send("kick %s"%(event.id))
						return
			if port == '1337':
				hack = True
		# else:
			# print 'not ip : ', event.id
		if hack :
			banTime = 0
			Admin = kiwi.config.configuration().kiwi.name
			arguments = 'Hacking Suspected (PORT or GUID not valid)'
			self.bdBan.insertBan(guid,ip,name,banTime,Admin,arguments)
			self.output.send("kick %s"%(event.id))
			return
		if not event.id in self.ClientsList:
			self.ClientsList.append((event.id, ip, name, guid))
	def checkClientHack(self, guid):
		guidMatch = re.compile('^[A-F0-9]{32}$')
		if not guidMatch.search(guid):
			return true
		return False
	def decoClient(self, event):
		for d in self.ClientsList:
			if event.id == d[0]:
				self.decoList = d[1], d[2], d[3]
				self.ClientsList.remove(d)
	def _be(self, event):
		if len(event.arguments) > 0:
			argu = ' '.join(event.arguments[0:])
		else:
			argu = "Ban exit !"
		temps = event.command
		print "temps : ", temps
		for p in temps[2:]:
			if p  != "+":
				return
		t = len(temps[2:])
		print 't:: ', t
		if t == 0 :
			nbtime = kiwi.getTime() + 3600 #1 heure
		elif t == 1 :
			nbtime = kiwi.getTime() + 86400 #1 jour
		elif t == 2 :
			nbtime = kiwi.getTime() + 604800 #1 semaine
		elif t == 3 :
			nbtime = kiwi.getTime() + 2592000 # mois
		elif t == 4:
			nbtime = kiwi.getTime() + 31104000 #1 an
		else:
			nbtime = 0
		if self.decoList:
			ip, name, guid = self.decoList
			Admin = self.clients.getClientById(event.id)[0].name
			self.bdBan.insertBan(guid,ip,name,nbtime,Admin,argu)
			self.output.tell(event.id,self.lang.lang(event,"00403"))
			self.output.send(self.lang.lang('',"00402")%(name, argu))
			self.main.log.ban(self.lang.lang('',"00404")%(Admin, name, argu))
			self.decoList = None
		else:
			self.output.tell(event.id, self.lang.lang(event,"00103"))
	def _ban(self, event):
		if len(event.arguments) > 0:
			if len(event.arguments) > 1:
				t = {'m':60,'h':3600, 'd':86400, 'w':604800, 'M':2592000, 'y':31104000}				
				if len(event.arguments) == 2:
					if event.arguments[1][-1] in t and event.arguments[1][:-1].isdigit():
						self.output.tell(event.id,self.lang.lang(event,"00407"))
						return
				arguments = ' '.join(event.arguments[1:])
				banTime = 0
				if len(event.arguments) > 2:
					if event.arguments[1][:-1].isdigit():
						if len(event.arguments[1]) < 2 or not event.arguments[1][-1] in t or not event.arguments[1][:-1].isdigit():
							self.output.tell(event.id, self.lang.lang(event,"00408"))
							return
						banTime = kiwi.getTime() + int(event.arguments[1][:-1]) * t[event.arguments[1][-1]]
						arguments = ' '.join(event.arguments[2:])
				self.banClient(event, banTime, arguments)
			else:
				self.output.tell(event.id,self.lang.lang(event,"00407"))
		else:
			self.output.tell(event.id,self.lang.lang(event,"00101"))
	def _bye(self, event):
		if len(event.arguments) > 0:
			banTime = kiwi.getTime() + 600
			if len(event.arguments) > 1:
				arguments = ' '.join(event.arguments[1:])
			else:
				arguments = "^7BAN ^110 ^7minutes"
			self.banClient(event, banTime, arguments)
		else:
			self.output.tell(event.id,self.lang.lang(event,"00101"))
	def _unban(self, event):
		if len(event.arguments) > 0:
			name = event.arguments[0]
			if self.bdBan.searchByName(name):
				client = self.bdBan.searchByName(name)
				if len(client) == 1 :
					self.bdBan.removeBan(client[0]['guid'])
					name = client[0]['name']
				else:
					for c in client:
						if c['timeban'] > kiwi.getTime() :
							self.bdBan.removeBan(c['guid'])
							name = c['name']
							self.output.tell(event.id,'^1%s ^4%s '%(name,self.lang.lang(event, '00411')))
							self.main.log.info(self.lang.lang('',"00413")%name)
			else:
				clients = self.bdBan.searchAll()
				if len(clients) > 0 :
					list = []
					for c in clients:
						if c['timeban'] > kiwi.getTime() :
							if name.lower() in c['name'].lower():
								if not c['name'] in list :
									list.append(c['name'])
					if list :
						text = "^1, ^7".join(list)+"^1."
						self.output.tell(event.id,"^4%s ^7%s"%(self.lang.lang(event,"00410"),text))
					else:
						self.output.tell(event.id,self.lang.lang(event,"00103"))
		else:
			# clients = self.bdBan.searchAll()
			# if len(clients) > 0 :
				# list = []
				# for c in clients:
					# if not c['name'] in list :
						# list.append(c['name'])
				# if list :
					# text = "^1, ^7".join(list)+"^1."
					# self.output.tell(event.id,"^4%s ^7%s"%(self.lang.lang(event,"00412"),text))
				# else:
			self.output.tell(event.id,self.lang.lang(event,"00101"))
